package com.tjp.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mysql.cj.util.StringUtils;
import com.tjp.mall.product.entity.CategoryBrandRelationEntity;
import com.tjp.mall.product.service.CategoryBrandRelationService;
import com.tjp.mall.product.vo.Catalog2VO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tjp.common.utils.PageUtils;
import com.tjp.common.utils.Query;

import com.tjp.mall.product.dao.CategoryDao;
import com.tjp.mall.product.entity.CategoryEntity;
import com.tjp.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> queryPageWithTree(Map<String, Object> params) {
        //1.查询所有商品分类信息
        List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
        //2.将商品分类信息拆解成树形结构
        List<CategoryEntity> collect = categoryEntities.stream().filter(categoryEntity -> {
            //找出一级分类
            return categoryEntity.getParentCid() == 0;
        }).map(categoryEntity -> {
            //根据一级分类找出子分类
            categoryEntity.setChildrens(getCategoryChildrens(categoryEntity, categoryEntities));
            return categoryEntity;
        }).sorted((entity1, entity2) -> {
            return (entity1.getSort() == null ? 0 : entity1.getSort()) - (entity2.getSort() == null ? 0 : entity2.getSort());
        }).collect(Collectors.toList());

        return collect;
    }

    /**
     *  通过递归根据一级分类查子分类
     * @param categoryEntity 一级分类
     * @param categoryEntities  总类别数据
     * @return
     */
    private List<CategoryEntity> getCategoryChildrens(CategoryEntity categoryEntity, List<CategoryEntity> categoryEntities) {
        //总分类数据条件筛选
        List<CategoryEntity> collect = categoryEntities.stream().filter(entity -> {
            //根据分类找出直属子分类
            //注意Long比较 如果不在-128 - 127之间 会new一个对象
            return entity.getParentCid().equals(categoryEntity.getCatId());
        }).map(entity -> {
            //根据直属子分类再找出下级子分类
            entity.setChildrens(getCategoryChildrens(entity, categoryEntities));
            return entity;
        }).sorted((entity1, entity2) -> {
            return (entity1.getSort() == null ? 0 : entity1.getSort()) - (entity2.getSort() == null ? 0 : entity2.getSort());
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void removeCategoryByIds(List<Long> asList) {
        //TODO  检查类别数据是否在其他业务中使用

        //批量逻辑删除操作
        baseMapper.deleteBatchIds(asList);
    }


    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();

        List<Long> path = this.findParentPath(catelogId, paths);
        Collections.reverse(path);
        return path.toArray(new Long[path.size()]);
    }

    public List<Long> findParentPath(Long catelogId, List<Long> paths) {
        paths.add(catelogId);
        CategoryEntity entity = this.getById(catelogId);
        if (entity.getParentCid() != 0) {
            findParentPath(entity.getParentCid(), paths);
        }
        return paths;
    }

    @Transactional
    @Override
    public void updateDetail(CategoryEntity category) {
        //先更新分类原始数据
        this.updateById(category);

        //再更新分类关联的名称数据
        String name = category.getName();
        if (!StringUtils.isNullOrEmpty(name)) {
            Long catId = category.getCatId();
            categoryBrandRelationService.updateCatNameByCatId(catId, name);

            // TODO 同步更新其他冗余数据
        }
    }

    @Override
    public List<CategoryEntity> getLeve1Category() {
        List<CategoryEntity> list = baseMapper.queryLeve1Category();

        return list;
    }

    /**
     * 根据父编号获取对应的子菜单信息
     * @param list
     * @param parentCid
     * @return
     */
    private List<CategoryEntity> queryByParenCid(List<CategoryEntity> list, Long parentCid){
        List<CategoryEntity> collect = list.stream().filter(item -> {
            return item.getParentCid().equals(parentCid);
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public Map<String, List<Catalog2VO>> getCatalog2JSON() {
        //获取所有分类数据
        List<CategoryEntity> allCatrgoryDatas = baseMapper.selectList(new QueryWrapper<CategoryEntity>());

        //获取一级分类数据
        List<CategoryEntity> level1Datas = this.queryByParenCid(list(), 1L);

        // 把一级分类的数据转换为Map容器 key就是一级分类的编号， value就是一级分类对应的二级分类的数据
        Map<String, List<Catalog2VO>> map = level1Datas.stream().collect(Collectors.toMap(key -> key.getCatId().toString(), value -> {
            //根据一级分类编号,查询出对应二级分裂编号
            List<CategoryEntity> level2Datas = this.queryByParenCid(allCatrgoryDatas, value.getCatId());

            List<Catalog2VO> catalog2VOs = null;
            if (level2Datas != null) {
                catalog2VOs = level2Datas.stream().map(l2 -> {
                    //将查询出来的二级分类数据填充到对应catalog2VO中
                    Catalog2VO catalog2VO = new Catalog2VO(l2.getParentCid().toString(), null, l2.getCatId().toString(), l2.getName());

                    //根据二级分类数据找到对应三级分类
                    List<CategoryEntity> level3Datas = this.queryByParenCid(allCatrgoryDatas, l2.getCatId());
                    if (level3Datas != null) {
                        List<Catalog2VO.Catalog3VO> catalog3VOS = level3Datas.stream().map(l3 -> {
                            //将三级分类数据填充到二级分类中
                            Catalog2VO.Catalog3VO catalog3VO = new Catalog2VO.Catalog3VO(l3.getParentCid().toString(), l3.getCatId().toString(), l3.getName());
                            return catalog3VO;
                        }).collect(Collectors.toList());
                        catalog2VO.setCatalog3List(catalog3VOS);
                    }
                    return catalog2VO;
                }).collect(Collectors.toList());
            }
            return catalog2VOs;
        }));

//        //找出一级分类数据
//        List<CategoryEntity> leve1List = this.getLeve1Category();
//        //将1级分类的数据转换为Map容器
//        Map<String, List<Catalog2VO>> map = leve1List.stream().collect(Collectors.toMap(key -> key.getCatId().toString(), value -> {
//            // 根据一级分类的编号，查询出对应的二级分类的数据
//            List<CategoryEntity> level2Catalogs = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", value.getCatId()));
//
//            List<Catalog2VO> catalog2VOList = null;
//            if (level2Catalogs != null) {
//                List<Catalog2VO> list = level2Catalogs.stream().map(l2 -> {
//                    //需要把查询出来的数据填充到对应的Catalog2VO中
//                    Catalog2VO catalog2VO = new Catalog2VO(l2.getParentCid().toString(), null, l2.getCatId().toString(), l2.getName());
//                    //根据二级找出三级
//                    List<CategoryEntity> level3Catalogs = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", catalog2VO.getId()));
//                    if (level3Catalogs != null) {
//                        List<Catalog2VO.Catalog3VO> catalog3VOS = level3Catalogs.stream().map(l3 -> {
//                            //将三级分类数据填充到二级分类中
//                            Catalog2VO.Catalog3VO catalog3VO = new Catalog2VO.Catalog3VO(l3.getParentCid().toString(), l3.getCatId().toString(), l3.getName());
//                            return catalog3VO;
//                        }).collect(Collectors.toList());
//                        catalog2VO.setCatalog3List(catalog3VOS);
//                    }
//                    return catalog2VO;
//                }).collect(Collectors.toList());
//                catalog2VOList = list;
//            }
//            return catalog2VOList;
//        }));
//
        return map;
    }
}